home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / uupc11ys.zip / LIB / CONFIGUR.C < prev    next >
C/C++ Source or Header  |  1993-04-15  |  30KB  |  786 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    c o n f i g u r . c                                             */
  3. /*                                                                    */
  4. /*    Support routines for UUPC/extended                              */
  5. /*                                                                    */
  6. /*    Changes Copyright 1990, 1991 (c) Andrew H. Derbyshire           */
  7. /*                                                                    */
  8. /*    History:                                                        */
  9. /*       21Nov1991 Break out of lib.c                          ahd    */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. /*--------------------------------------------------------------------*/
  13. /*    Changes Copyright (c) 1989 by Andrew H. Derbyshire.             */
  14. /*                                                                    */
  15. /*    Changes Copyright (c) 1990-1993 by Kendra Electronic            */
  16. /*    Wonderworks.                                                    */
  17. /*                                                                    */
  18. /*    All rights reserved except those explicitly granted by the      */
  19. /*    UUPC/extended license agreement.                                */
  20. /*--------------------------------------------------------------------*/
  21.  
  22. /*--------------------------------------------------------------------*/
  23. /*                          RCS Information                           */
  24. /*--------------------------------------------------------------------*/
  25.  
  26. /*
  27.  *    $Id: CONFIGUR.C 1.10 1993/04/15 03:17:21 ahd Exp $
  28.  *
  29.  *    Revision history:
  30.  *    $Log: CONFIGUR.C $
  31.  *     Revision 1.10  1993/04/15  03:17:21  ahd
  32.  *     Add bounce system option
  33.  *
  34.  *     Revision 1.9  1993/04/11  00:31:31  dmwatt
  35.  *     Global edits for year, TEXT, etc.
  36.  *
  37.  *     Revision 1.8  1993/04/05  04:32:19  ahd
  38.  *     Set timezone, windows input mode in common routine
  39.  *
  40.  *     Revision 1.7  1993/04/04  04:57:01  ahd
  41.  *     Default configuration directory from UUPCSYSRC
  42.  *     Default system directories from Configuration directory
  43.  *
  44.  *     Revision 1.6  1993/03/06  22:48:23  ahd
  45.  *     Don't fall off end of shorter tables
  46.  *
  47.  *     Revision 1.5  1993/01/23  19:08:09  ahd
  48.  *     Add Windows/NT to allowed environments
  49.  *
  50.  * Revision 1.4  1992/12/01  04:37:03  ahd
  51.  * Add SpeedOverMemory
  52.  *
  53.  * Revision 1.3  1992/11/22  20:58:55  ahd
  54.  * Normalize directories as read
  55.  * Use strpool to allocate const strings
  56.  *
  57.  * Revision 1.2  1992/11/19  02:56:47  ahd
  58.  * drop rcsid
  59.  *
  60.  * Revision 1.1  1992/11/16  05:00:26  ahd
  61.  * Initial revision
  62.  *
  63.  */
  64.  
  65.  
  66. #include <stdio.h>
  67. #include <stdlib.h>
  68. #include <string.h>
  69. #include <time.h>
  70. #include <ctype.h>
  71.  
  72. #ifndef __GNUC__
  73. #include <io.h>
  74. #endif
  75.  
  76. /*--------------------------------------------------------------------*/
  77. /*                    UUPC/extended include files                     */
  78. /*--------------------------------------------------------------------*/
  79.  
  80. #include "lib.h"
  81. #include "hlib.h"
  82. #include "timestmp.h"
  83. #include "pushpop.h"
  84.  
  85. /*--------------------------------------------------------------------*/
  86. /*                          Global variables                          */
  87. /*--------------------------------------------------------------------*/
  88.  
  89. currentfile();
  90.  
  91. boolean bflag[F_LAST];        /* Initialized to zero by compiler     */
  92.  
  93. char *E_aliases = NULL;
  94. char *E_anonymous = NULL;
  95. char *E_archivedir = NULL;
  96. char *E_confdir = NULL;
  97. char *E_domain = NULL;
  98. char *E_altsignature = NULL;
  99. char *E_backup = NULL;
  100. char *E_charset = NULL;
  101. char *E_editor = NULL;
  102. char *E_filesent = NULL;
  103. char *E_inmodem = NULL;
  104. char *E_mailext = NULL;
  105. char *E_pager = NULL;
  106. char *E_signature = NULL;
  107. char *E_uuxqtpath = NULL;
  108. char *E_fdomain = NULL;
  109. char *E_homedir = NULL;
  110. char *E_localdomain = NULL;
  111. char *E_mailbox = NULL;
  112. char *E_maildir = NULL;
  113. char *E_mailserv = NULL;
  114. char *E_name = NULL;
  115. char **E_internal = NULL;
  116. char *E_newsdir = NULL;
  117. char *E_newsserv = NULL;
  118. char *E_nodename = NULL;
  119. char *E_organization = NULL;
  120. char *E_postmaster = NULL;
  121. char *E_pubdir = NULL;
  122. char *E_replyto = NULL;
  123. char *E_spooldir = NULL;
  124. char *E_tempdir = NULL;
  125. char *E_version = NULL;
  126. char *E_uncompress = NULL;
  127. static char *dummy = NULL;
  128. INTEGER E_priority = -99;
  129. INTEGER E_prioritydelta = -99;
  130.  
  131. INTEGER E_maxhops = 20;                                     /* ahd */
  132.  
  133. /*--------------------------------------------------------------------*/
  134. /*                       Local emumerated types                       */
  135. /*--------------------------------------------------------------------*/
  136.  
  137. typedef enum {
  138.       OS2_ENV,
  139.       DOS_ENV,
  140.       WIN32_ENV,
  141.       UNKNOWN_ENV
  142.       } ENV_TYPE;
  143.  
  144. #ifdef WIN32
  145. static ENV_TYPE active_env = WIN32_ENV;
  146. #else
  147. static ENV_TYPE active_env = DOS_ENV;
  148. #endif
  149.  
  150. static boolean getrcnames(char **sysp,char **usrp);
  151.  
  152. /*--------------------------------------------------------------------*/
  153. /*  The following table controls the configuration files processing   */
  154. /*--------------------------------------------------------------------*/
  155.  
  156. static CONFIGTABLE envtable[] = {
  157.    {"aliases",      &E_aliases,      B_TOKEN|B_MUA},
  158.    {"altsignature", &E_altsignature, B_TOKEN|B_MUA},
  159.    {"anonymouslogin",
  160.                     &E_anonymous,    B_GLOBAL|B_TOKEN|(B_ALL & ~ B_MAIL)},
  161.    {"archivedir",   &E_archivedir,   B_GLOBAL|B_PATH|B_ALL},
  162.    {"backupext",    &E_backup,       B_TOKEN|B_MUA},
  163.    {"confdir",      &E_confdir,      B_GLOBAL|B_PATH|B_ALL},
  164.    {"charset",      &E_charset,      B_TOKEN|B_GLOBAL|B_SPOOL},
  165.    {"domain",       &E_domain,       B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL},
  166.    {"editor",       &E_editor,       B_STRING|B_MUA|B_NEWS},
  167.    {"filesent",     &E_filesent,     B_TOKEN|B_MUA|B_NEWS},
  168.    {"folders",      &dummy,          B_PATH|B_MUSH },
  169.    {"fromdomain",   &E_fdomain,      B_GLOBAL|B_MAIL|B_NEWS|B_TOKEN},
  170.    {"home",         &E_homedir,      B_PATH|B_REQUIRED|B_ALL},
  171.    {"inmodem",      &E_inmodem,      B_GLOBAL|B_TOKEN|B_UUCICO},
  172.    {"internalcommands", (char **)   &E_internal,
  173.                                      B_GLOBAL|B_LIST|B_UUXQT},
  174.    {"localdomain",  &E_localdomain,  B_GLOBAL|B_TOKEN|B_MAIL},
  175.    {"mailbox",      &E_mailbox,      B_REQUIRED|B_TOKEN|B_ALL},
  176.    {"mailext",      &E_mailext,      B_TOKEN|B_MAIL},
  177.    {"maildir",      &E_maildir,      B_GLOBAL|B_PATH|B_ALL},
  178.    {"mailserv",     &E_mailserv,     B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL},
  179.    {"maximumhops",  (char **) &E_maxhops,
  180.                                      B_MTA | B_INTEGER | B_GLOBAL},
  181.    {"mushdir",      &dummy,          B_GLOBAL|B_PATH|B_MUSH},
  182.    {"name",         &E_name,         B_REQUIRED|B_MAIL|B_NEWS|B_STRING},
  183.    {"newsdir",      &E_newsdir,      B_GLOBAL|B_PATH|B_ALL},
  184.    {"newsserv",     &E_newsserv,     B_GLOBAL|B_TOKEN|B_NEWS},
  185.    {"nodename",     &E_nodename,     B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL},
  186.    {"options",      (char **) bflag, B_ALL|B_BOOLEAN},
  187.    {"organization", &E_organization, B_STRING|B_MAIL|B_NEWS},
  188.    {"pager",        &E_pager,        B_STRING|B_MUA|B_NEWS},
  189.    {"path",         &E_uuxqtpath,    B_STRING|B_UUXQT|B_GLOBAL},
  190.    {"postmaster",   &E_postmaster,   B_REQUIRED|B_GLOBAL|B_TOKEN|B_MTA},
  191.    {"pubdir",       &E_pubdir,       B_GLOBAL|B_PATH|B_ALL},
  192.    {"priority",     (char **) &E_priority,
  193.                                      B_INTEGER |B_UUCICO},
  194.    {"prioritydelta",(char **) &E_prioritydelta,
  195.                                      B_INTEGER |B_UUCICO},
  196.    {"replyto",      &E_replyto,      B_TOKEN|B_MAIL|B_NEWS},
  197.    {"signature",    &E_signature,    B_TOKEN|B_MUA|B_NEWS},
  198.    {"spooldir",     &E_spooldir,     B_GLOBAL|B_PATH|B_ALL},
  199.    {"tempdir",      &E_tempdir,      B_GLOBAL|B_PATH|B_ALL},
  200.    {"uncompress",   &E_uncompress,   B_GLOBAL|B_STRING|B_NEWS },
  201.    {"version",      &E_version,      B_TOKEN|B_INSTALL},
  202.    {"rmail",        &dummy,          B_OBSOLETE },
  203.    {"rnews",        &dummy,          B_OBSOLETE },
  204.    { nil(char) }
  205. }; /* table */
  206.  
  207. /*--------------------------------------------------------------------*/
  208. /*               Boolean options shared by all programs               */
  209. /*--------------------------------------------------------------------*/
  210.  
  211. FLAGTABLE configFlags[] = {
  212.  { "askcc",       F_ASKCC,       B_LOCAL},
  213.  { "autoedit",    F_AUTOEDIT,    B_LOCAL},
  214.  { "autoinclude", F_AUTOINCLUDE, B_LOCAL},
  215.  { "autoprint",   F_AUTOPRINT,   B_LOCAL},
  216.  { "autosign",    F_AUTOSIGN,    B_LOCAL},
  217.  { "backup",      F_BACKUP,      B_LOCAL},
  218.  { "doskey",      F_DOSKEY,      B_LOCAL},
  219.  { "dot",         F_DOT,         B_LOCAL},
  220.  { "expert",      F_EXPERT,      B_LOCAL},
  221.  { "forwardsave", F_SAVERESENT,  B_LOCAL},
  222.  { "fromsep",     F_FROMSEP,     B_LOCAL},
  223.  { "pager",       F_PAGER,       B_LOCAL},
  224.  { "purge",       F_PURGE,       B_LOCAL},
  225.  { "save",        F_SAVE,        B_LOCAL},
  226.  { "suppresscopyright",
  227.                   F_SUPPRESSCOPYRIGHT,
  228.                                  B_LOCAL},
  229.  { "speedovermemory",
  230.                   F_SPEEDOVERMEMORY,
  231.                                  B_LOCAL},
  232.  { "verbose",     F_VERBOSE,     B_LOCAL},
  233.  { "undelete",    F_UNDELETE,    B_LOCAL},
  234.  
  235.  { "bang",        F_BANG,        B_GLOBAL},
  236.  { "bounce",      F_BOUNCE,      B_GLOBAL},
  237.  { "collect",     F_COLLECTSTATS,B_GLOBAL},
  238.  { "directory",   F_DIRECT,      B_GLOBAL},
  239.  { "escape",      F_ESCAPE,      B_GLOBAL},
  240.  { "hpfs",        F_HPFS,        B_GLOBAL},
  241.  { "history",     F_HISTORY,     B_GLOBAL},
  242.  { "kanji",       F_KANJI,       B_GLOBAL},
  243.  { "monocase",    F_ONECASE,     B_GLOBAL},
  244.  { "multiqueue",  F_MULTI,       B_GLOBAL},
  245.  { "multitask",   F_MULTITASK,   B_GLOBAL},
  246.  { "snews",       F_SNEWS,       B_GLOBAL},
  247.  { "syslog",      F_SYSLOG,      B_GLOBAL},
  248.  { "symmetricgrades",
  249.                   F_SYMMETRICGRADES,
  250.                                  B_GLOBAL},
  251.  
  252.  { nil(char) }
  253. }           ;
  254.  
  255. /*--------------------------------------------------------------------*/
  256. /*    p r o c e s s c o n f i g                                       */
  257. /*                                                                    */
  258. /*    Handle a single line of a configuration file                    */
  259. /*--------------------------------------------------------------------*/
  260.  
  261. boolean processconfig(char *buff,
  262.                   SYSMODE sysmode,
  263.                   CONFIGBITS program,
  264.                   CONFIGTABLE *table,
  265.                   FLAGTABLE *btable)
  266. {
  267.    CONFIGTABLE *tptr;
  268.    char *cp;
  269.    char *keyword;
  270.    ENV_TYPE target_env;
  271.  
  272. /*--------------------------------------------------------------------*/
  273. /*                break out the keyword from its value                */
  274. /*--------------------------------------------------------------------*/
  275.  
  276.    if ((cp = strchr(buff, '=')) == nil(char))
  277.    {
  278.       printmsg(0,"Missing equals sign after keyword \"%s\", ignored",
  279.                   buff);
  280.       return TRUE;
  281.    }
  282.    *cp++ = '\0';
  283.    strlwr(buff);
  284.  
  285. /*--------------------------------------------------------------------*/
  286. /*    Determine if the keyword should processed in this environment   */
  287. /*--------------------------------------------------------------------*/
  288.  
  289.    keyword = strchr( buff, '.' );   /* Look for environment          */
  290.  
  291.    if ( keyword == NULL )     /* No environment?                     */
  292.    {
  293.       keyword = buff;         /* Then buffer starts with keyword     */
  294.       target_env = active_env;
  295.    }
  296.    else {
  297.       *keyword++ = '\0';      /* Terminate environment string        */
  298.  
  299.       if ( equal( buff, "dos" ))
  300.          target_env = DOS_ENV;
  301.       else if ( equal( buff, "os2" ))
  302.          target_env = OS2_ENV;
  303.       else if ( equal( buff, "win32" ))
  304.          target_env = WIN32_ENV;
  305.       else {
  306.          printmsg(0,"Unknown environment \"%s\", keyword \"%s\" ignored",
  307.                buff, keyword );
  308.          return FALSE;
  309.       } /* else */
  310.    } /* else */
  311.  
  312. /*--------------------------------------------------------------------*/
  313. /*                    Scan the table for its value                    */
  314. /*--------------------------------------------------------------------*/
  315.  
  316.    for (tptr = table; tptr->sym != nil(char); tptr++)
  317.    {
  318.       boolean error = FALSE;
  319.       if (equal(keyword, tptr->sym)) {
  320. /*--------------------------------------------------------------------*/
  321. /*            Skip the keyword because of the environment?            */
  322. /*--------------------------------------------------------------------*/
  323.         if (active_env != target_env )
  324.             printmsg(2,"%s-only keyword \"%s\" skipped.",
  325.                         buff, keyword);
  326. /*--------------------------------------------------------------------*/
  327. /*                      Handle obsolete options                       */
  328. /*--------------------------------------------------------------------*/
  329.         else if (tptr->bits & B_OBSOLETE)
  330.             printmsg(2,"Obsolete keyword \"%s\" ignored.", keyword);
  331. /*--------------------------------------------------------------------*/
  332. /*                  Handle mis-placed system options                  */
  333. /*--------------------------------------------------------------------*/
  334.         else if ((tptr->bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
  335.             printmsg(0,
  336.                "User specified system keyword \"%s\" ignored.",
  337.                keyword);
  338. /*--------------------------------------------------------------------*/
  339. /*                       Handle Boolean options                       */
  340. /*--------------------------------------------------------------------*/
  341.          else {
  342.             if (tptr->bits & B_BOOLEAN)
  343.                options(cp, sysmode, btable, (boolean *) tptr->loc);
  344. /*--------------------------------------------------------------------*/
  345. /*                       Handle integer values                        */
  346. /*--------------------------------------------------------------------*/
  347.             else if (tptr->bits & B_INTEGER)
  348.             {
  349.                int *value = (int *) tptr->loc;
  350.                cp = strtok(cp,WHITESPACE);
  351.                if ( equal(cp,"0"))
  352.                   *value = 0;
  353.                else {
  354.                   *value = atoi(cp);
  355.                   if ( *value == 0)
  356.                   {
  357.                      printmsg(0,
  358.                         "Unable to convert \"%s\" value \"%s\" to integer",
  359.                         keyword, cp);
  360.                      error = TRUE;
  361.                   } /* if */
  362.                } /* else */
  363.             } /* else */
  364. /*--------------------------------------------------------------------*/
  365. /*                       Handle lists of tokens                       */
  366. /*--------------------------------------------------------------------*/
  367.             else if ((tptr->bits & program) && (tptr->bits & (B_LIST | B_CLIST)))
  368.             {
  369.                char **list = malloc( (MAXLIST+1) * sizeof (*list));
  370.                char *colon;
  371.                int words;
  372.  
  373.                checkref( list );
  374.  
  375.                if (tptr->bits & B_CLIST)  /* Use colon as delimiter? */
  376.                   while ( (colon = strchr( cp , ':')) != NULL)
  377.                      *colon = ' ';     /* Make colons spaces ...           */
  378.  
  379.                words = getargs(cp, list);
  380.                if( words > MAXLIST)
  381.                   panic();
  382.  
  383.                if (words > 0)
  384.                {
  385.                   if ( *(tptr->loc) )
  386.                      free( *(tptr->loc) );
  387.                   list = realloc( list, (words+1) * sizeof(*list));
  388.                   checkref( list );
  389.                   *(tptr->loc) = (char *) list;
  390.                   list[words] = NULL;
  391.  
  392.                   while( *list != NULL)
  393.                   {
  394.                      if (strlen(*list))
  395.                      {
  396.                         *list = newstr(*list);
  397.                         checkref( *list++ );
  398.                      }
  399.                      else
  400.                         *list++ = "";
  401.                   } /* while */
  402.                } /* if (words > 0) */
  403.                else {
  404.                   printmsg(0,"No parameters given for keyword \"%s\"",
  405.                            keyword);
  406.                   error = TRUE;
  407.                } /* else */
  408.             } /* else if */
  409. /*--------------------------------------------------------------------*/
  410. /*                  Handle single tokens and strings                  */
  411. /*--------------------------------------------------------------------*/
  412.             else if (tptr->bits & program)
  413.             {
  414.                while( *cp == ' ' )     /* Trim leading whitespace    */
  415.                   cp++;
  416.  
  417.                if (*cp == '\0')
  418.                {
  419.                   error = TRUE;
  420.                   printmsg(0,"No parameter given for keyword \"%s\""
  421.                            ", ignored.",
  422.                            keyword);
  423.                } /* if */
  424.  
  425.                if (tptr->bits & B_TOKEN)  /* One word value?      */
  426.                   cp = strtok(cp,WHITESPACE); /* Yes --> Tokenize */
  427.  
  428.                if (tptr->bits & B_NORMAL)  /* Normalize path?     */
  429.                   cp = normalize( cp );
  430.  
  431.                if (tptr->bits & B_MALLOC)  /* Allocate normally?  */
  432.                {
  433.                   *(tptr->loc) = strdup(cp); /* Save string          */
  434.                   checkref( *(tptr->loc) );  /* Verify malloc()      */
  435.                }
  436.                else
  437.                   *(tptr->loc) = newstr(cp); /* Save string          */
  438.  
  439.             } /* else */
  440.          } /* else */
  441.  
  442.          if (!error)
  443.             tptr->bits |= B_FOUND;
  444.          return TRUE;         /* Report we found the keyword      */
  445.       } /* if (equal(keyword, tptr->sym)) */
  446.    } /* for */
  447.  
  448. /*--------------------------------------------------------------------*/
  449. /*      We didn't find the keyword; report failure to the caller      */
  450. /*--------------------------------------------------------------------*/
  451.  
  452.    return FALSE;
  453.  
  454. } /* processconfig */
  455.  
  456. /*--------------------------------------------------------------------*/
  457. /*    g e t c o n f i g                                               */
  458. /*                                                                    */
  459. /*    Process a single configuration file                             */
  460. /*--------------------------------------------------------------------*/
  461.  
  462. boolean getconfig(FILE *fp,
  463.                   SYSMODE sysmode,
  464.                   CONFIGBITS program,
  465.                   CONFIGTABLE *table,
  466.                   FLAGTABLE *btable)
  467. {
  468.  
  469.    char buff[BUFSIZ];
  470.    char *cp;
  471.  
  472.    while(!(fgets(buff, sizeof buff, fp) == nil(char))) {
  473.  
  474. /*--------------------------------------------------------------------*/
  475. /*                        Ingore comment lines                        */
  476. /*--------------------------------------------------------------------*/
  477.  
  478.       if (*buff == '#')
  479.          continue;            /* comment line   */
  480.  
  481. /*--------------------------------------------------------------------*/
  482. /*                       Drop trailing new line                       */
  483. /*--------------------------------------------------------------------*/
  484.  
  485.       if (*(cp = buff + strlen(buff) - 1) == '\n')
  486.          *cp = '\0';
  487.  
  488. /*--------------------------------------------------------------------*/
  489. /*                 Drop leading blanks on input line                  */
  490. /*--------------------------------------------------------------------*/
  491.  
  492.       cp = buff;
  493.       while( isspace( *cp ) )
  494.          cp ++ ;
  495.  
  496. /*--------------------------------------------------------------------*/
  497. /*                 If line was not blank, process it.                 */
  498. /*--------------------------------------------------------------------*/
  499.  
  500.       if ( (*cp != '\0') && !processconfig(cp,sysmode,program,table,btable))
  501.          printmsg(0,
  502.                "Unknown keyword \"%s\" in %s configuration file ignored",
  503.                buff, sysmode ? "system" : "user");
  504.  
  505.    } /*while*/
  506.  
  507.    return TRUE;
  508.  
  509. } /*getconfig*/
  510.  
  511. /*--------------------------------------------------------------------*/
  512. /*    o p t i o n s                                                   */
  513. /*                                                                    */
  514. /*    Process a line of boolean option flags.                         */
  515. /*--------------------------------------------------------------------*/
  516.  
  517. void options(char *s, SYSMODE sysmode , FLAGTABLE *flags, boolean *barray)
  518. {
  519.    char *token;
  520.  
  521.    strlwr(s);
  522.    token = strtok(s,WHITESPACE);
  523.  
  524.    while (token != NULL)
  525.    {
  526.       size_t subscript;
  527.       boolean hit = FALSE;
  528.       boolean negate;
  529.       negate = equaln(token,"no",2) && (strlen(token) > 2);
  530.  
  531.       for ( subscript=0; (flags[subscript].sym != NULL ) && !hit; subscript++)
  532.       {
  533.          if ((flags[subscript].bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
  534.             continue;
  535.          if (negate)
  536.          {
  537.             if (equal(&token[2],flags[subscript].sym))
  538.             {
  539.                barray[ flags[subscript].position ] = FALSE;
  540.                hit = TRUE;
  541.             }
  542.          } /* if negate */
  543.          else {
  544.             if (equal(token,flags[subscript].sym))
  545.             {
  546.                barray[ flags[subscript].position ] = TRUE;
  547.                hit = TRUE;
  548.             }
  549.          } /* else */
  550.       } /* for */
  551.  
  552.       if (!hit)
  553.          printf("Invalid or system option '%s' specified\n",token);
  554.  
  555.       token = strtok(NULL,WHITESPACE);  /* Step to next token on line */
  556.  
  557.    } /* while */
  558. } /* options */
  559.  
  560. /*--------------------------------------------------------------------*/
  561. /*    c o n f i g u r e                                               */
  562. /*                                                                    */
  563. /*    Define the global parameters of UUPC/extended                   */
  564. /*--------------------------------------------------------------------*/
  565.  
  566. boolean configure( CONFIGBITS program)
  567. {
  568.    char *sysrc, *usrrc;
  569.    FILE *fp;
  570.    boolean success;
  571.    char buf[BUFSIZ];
  572.    int subscript = 0;
  573.    char *s;
  574.  
  575.    CONFIGTABLE *tptr;
  576.  
  577.    static char *envlist[] = { "EDITOR",   "EDITOR",
  578.                               "HOME",     "HOME",
  579.                               "NAME",     "NAME",
  580.                               "MAILBOX",  "MAILBOX",
  581.                               "TEMP",     "TEMPDIR",
  582.                               "TMP",      "TEMPDIR",
  583.                               NULL } ;
  584.  
  585.    typedef struct _DEFAULTS {
  586.       char **value;
  587.       char *literal;
  588.    } DEFAULTS;
  589.  
  590.    static DEFAULTS deflist[] = {
  591.         {&E_archivedir,   "archive" },
  592.         {&E_maildir,      "mail"    },
  593.         {&E_newsdir,      "news"    },
  594.         {&E_pubdir,       "public"  },
  595.         {&E_spooldir,     "spool"   },
  596.         {&E_tempdir,      "tmp"     },
  597.         { NULL  }
  598.         } ;
  599.  
  600. /*--------------------------------------------------------------------*/
  601. /*     In Windows/NT, set the console input mode to non-linebased     */
  602. /*--------------------------------------------------------------------*/
  603.  
  604. #ifdef WIN32
  605.    setstdinmode();
  606. #endif
  607.  
  608. /*--------------------------------------------------------------------*/
  609. /*                         Set our time zone                          */
  610. /*--------------------------------------------------------------------*/
  611.  
  612.    if (getenv("TZ") == NULL )
  613.    {
  614.       printmsg(0,"Environment variable TZ must be set!");
  615.       panic();
  616.    }
  617.    tzset();                      /* Set up time zone information  */
  618.  
  619. /*--------------------------------------------------------------------*/
  620. /*                  Determine the active environment                  */
  621. /*--------------------------------------------------------------------*/
  622.  
  623. #ifndef __TURBOC__
  624. #ifndef __GNUC__
  625.    if (_osmode != DOS_MODE)
  626.       active_env = OS2_ENV;
  627. #endif
  628. #endif
  629.  
  630.    if (!getrcnames(&sysrc, &usrrc))
  631.       return FALSE;
  632.  
  633. /*--------------------------------------------------------------------*/
  634. /*          Extract selected variables from our environment           */
  635. /*--------------------------------------------------------------------*/
  636.  
  637.    while( envlist[subscript] != NULL )
  638.    {
  639.       s = getenv( envlist[subscript++] );
  640.  
  641.       if (s != NULL )
  642.       {
  643.          sprintf(buf,"%s=%s",envlist[subscript], s );
  644.          processconfig( buf, SYSTEM_CONFIG, program, envtable, configFlags);
  645.       } /* if (sysrc != NULL ) */
  646.  
  647.       subscript++;            /* Step to next environment var in list   */
  648.    }
  649.  
  650. /*--------------------------------------------------------------------*/
  651. /*          Determine configuration directory from UUPCSYSRC          */
  652. /*--------------------------------------------------------------------*/
  653.  
  654.    E_confdir = normalize( sysrc );     // Make 'em all slashes
  655.  
  656.    s = strrchr( E_confdir, '/' );      // Get end of path component
  657.    if ( s == NULL )                    // There WAS one, right?
  658.    {                                   // Er, no, sorry.
  659.       printmsg(0,"No path name in UUPCSYSRC: %s", sysrc);
  660.       panic();
  661.    }
  662.  
  663.    *s = '\0';                          // Terminate for Config Directory
  664.    E_confdir = newstr( E_confdir );    // Save in permanent pool
  665.  
  666. /*--------------------------------------------------------------------*/
  667. /*               Process the system configuration file                */
  668. /*--------------------------------------------------------------------*/
  669.  
  670.    if ((fp = FOPEN(sysrc, "r",TEXT_MODE)) == nil(FILE))
  671.    {
  672.       printmsg(0, "Cannot open system configuration file \"%s\"", sysrc);
  673.       printerr(sysrc);
  674.       return FALSE;
  675.    }
  676.  
  677.    PushDir( E_confdir );
  678.  
  679.    success = getconfig(fp, SYSTEM_CONFIG, program, envtable, configFlags);
  680.  
  681.    fclose(fp);
  682.    if (!success)
  683.    {
  684.       PopDir();
  685.       return FALSE;
  686.    }
  687.  
  688. /*--------------------------------------------------------------------*/
  689. /*                Process the user configuration value                */
  690. /*--------------------------------------------------------------------*/
  691.  
  692.    if (usrrc != nil(char))
  693.    {
  694.       usrrc = normalize( usrrc );
  695.       if ((fp = FOPEN(usrrc, "r",TEXT_MODE)) == nil(FILE))
  696.       {
  697.          printmsg(0, "Cannot open user configuration file \"%s\"", usrrc);
  698.          PopDir();
  699.          return FALSE;
  700.       }
  701.  
  702.       success = getconfig(fp, USER_CONFIG, program, envtable, configFlags);
  703.       fclose(fp);
  704.  
  705.       if (!success)
  706.       {
  707.          PopDir();
  708.          return FALSE;
  709.       }
  710.  
  711.    }
  712.  
  713. /*--------------------------------------------------------------------*/
  714. /*                       Display our copyright                        */
  715. /*--------------------------------------------------------------------*/
  716.  
  717.    if (! bflag[F_SUPPRESSCOPYRIGHT] &&
  718.         (program != B_MTA) &&
  719.         isatty(fileno(stdout)))
  720.       fprintf(stdout,
  721. "Changes and Compilation Copyright (c) 1990-1993 by Kendra Electronic\n"
  722. "Wonderworks.  May be freely distributed if original documentation and\n"
  723. "source is included.\n" );
  724.  
  725. /*--------------------------------------------------------------------*/
  726. /*          Validate that all required parameters were given          */
  727. /*--------------------------------------------------------------------*/
  728.  
  729.    for (tptr = envtable; tptr->sym != nil(char); tptr++)
  730.    {
  731.  
  732.       if ((tptr->bits & (B_REQUIRED | B_FOUND)) == B_REQUIRED)
  733.       {
  734.          printmsg(0, "%s configuration parameter \"%s\" must be set.",
  735.             (tptr->bits & B_GLOBAL) ? "System" : "User",
  736.             tptr->sym);
  737.          success = FALSE;
  738.       } /* if */
  739.  
  740.    } /* for */
  741.  
  742. /*--------------------------------------------------------------------*/
  743. /*                     Fill in derived parameters                     */
  744. /*--------------------------------------------------------------------*/
  745.  
  746.    subscript = 0;
  747.    while( deflist[subscript].value != NULL )
  748.    {
  749.       if ( *(deflist[subscript].value) == NULL )
  750.          *(deflist[subscript].value) =
  751.                      newstr( normalize(deflist[subscript].literal ) );
  752.       subscript++;
  753.    }
  754.  
  755.    PopDir();
  756.    return success;
  757.  
  758. } /*configure*/
  759.  
  760. /*--------------------------------------------------------------------*/
  761. /*    g e t r c n a m e s                                             */
  762. /*                                                                    */
  763. /*    Return the name of the configuration files                      */
  764. /*--------------------------------------------------------------------*/
  765.  
  766. static boolean getrcnames(char **sysp,char **usrp)
  767. {
  768.    char *debugp = NULL;      /* Pointer to debug environment variable  */
  769.  
  770.    if ((*sysp = getenv(SYSRCSYM)) == nil(char))
  771.    {
  772.       printf("environment variable %s must be specified\n", SYSRCSYM);
  773.       return FALSE;
  774.    }
  775.  
  776.    *usrp = getenv(USRRCSYM);
  777.  
  778.    debugp = getenv(SYSDEBUG);
  779.  
  780.    if ( debugp != nil(char))        /* Debug specified in environment?     */
  781.       debuglevel = atoi(debugp);    /* Yes --> preset debuglevel for user  */
  782.  
  783.    return TRUE;
  784.  
  785. } /*getrcnames*/
  786.